#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "Log.hpp"
using std::cout;
using std::cin;
using std::endl;
extern Log log;


struct ThreadData
{
    struct sockaddr_in server;
    int sockfd;
};



//客户端不仅要能发数据(线程A), 还要能够收数据(线程B)
class udp_client
{
private:
    int _sockfd = 0;

public:
    udp_client(){}
    ~udp_client(){if(_sockfd > 0)close(_sockfd); }

    void Init();
    void Run();

    //线程A收数据
    static void* recv_message(void* arg);

    //线程B发数据
    static void* send_message(void* arg);
};

void udp_client::Init()
{
    //创建套接字
    _sockfd = socket(AF_INET, SOCK_DGRAM, 0);//可能创建失败
    if(_sockfd < 0){ log(Fatal, "create socket fali "); exit(1);}
    log(Info, "create socket success %d",_sockfd);

}

//主线程
void udp_client::Run()
{
    //填充服务器信息
    ThreadData td;
    memset(&td.server, 0, sizeof(td.server));
    td.server.sin_family = AF_INET;
    td.server.sin_port = htons(8080);
    td.server.sin_addr.s_addr = inet_addr("120.53.91.43");
    td.sockfd = _sockfd;

    pthread_t recvr, sender;
    pthread_create(&recvr, nullptr, recv_message, &td);
    pthread_create(&sender, nullptr, send_message, &td);
   
    pthread_join(recvr,nullptr);
    pthread_join(sender,nullptr);

    close(_sockfd);
}

//线程A收数据
void* udp_client::recv_message(void* arg)
{
    ThreadData* td = (ThreadData*)arg;
    char buffer[1024];
    while(1)
    {
        ssize_t s = recvfrom(td->sockfd, buffer, sizeof(buffer), 0, NULL, NULL);//可以做个判断
        cout << buffer << endl;
        memset(buffer, 0, sizeof(buffer));
    }
}

//线程B发数据
void* udp_client::send_message(void* arg)
{
    ThreadData* td = (ThreadData*)arg;
    std::string message;
    socklen_t len = sizeof(td->server);
    while(1)
    {
        cout << "Please Enter@ ";
        std::string message;
        getline(cin , message);
        
        sendto(td->sockfd, message.c_str(), message.size(), 0, (sockaddr*)&(td->server), len);
        cout << message << endl;
    }
}



    // while(1)
    // {
    //     //1.发送数据
    //     std::string message;
    //     std::getline(cin, message);
    //     sendto(_sockfd, message.c_str(), sizeof(message), 0 , (sockaddr*)&server, sizeof(server));
    //     cout << "client say " << message << endl;
    //     if(message == "quit")break;

    //     //2.接收数据
    //     char inbuffer[1024];
    //     recvfrom(_sockfd, inbuffer, sizeof(inbuffer) , 0, NULL, NULL);
    //     cout << "server say: " << inbuffer << endl;

    //     memset(inbuffer, 0, sizeof(inbuffer));
    // }

    // log(Info, "client quit");


